package org.skydiveapphd;

import java.util.Date;

import org.skydiveapphd.interfaces.NotesNotifier;
import org.skydiveapphd.interfaces.RigComponentNotifier;
import org.skydiveapphd.interfaces.RigReminderNotifier;
import org.skydiveapphd.ui.FragmentHelper;
import org.skydiveapplibrary.R;
import org.skydiveapplibrary.data.Rig;
import org.skydiveapplibrary.data.RigComponent;
import org.skydiveapplibrary.data.RigReminder;
import org.skydiveapplibrary.data.TimeUnit;
import org.skydiveapplibrary.data.RigReminder.DueStatus;
import org.skydiveapplibrary.repository.RigRepository;
import org.skydiveapplibrary.ui.FormatUtility;
import org.skydiveapplibrary.ui.TableStyler;
import org.skydiveapplibrary.ui.TableStyler.TableRowLocation;
import org.skydiveapplibrary.util.RigReminderManager;

import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class RigEditActivity extends Fragment implements NotesNotifier, RigComponentNotifier, RigReminderNotifier
{
	// repositories
	private RigRepository repository;
	
	// data
	private boolean isEdit = false;
	private Rig rig;
	private RigComponent currentEditedComponent;
	private RigReminder currentEditedReminder;
	private boolean isUpdated = false;
	
	public static RigEditActivity newInstance(Bundle args) 
	{
		RigEditActivity f = new RigEditActivity();
		f.setArguments(args);
		return f;
	}
	
	// listeners
	private OnClickListener saveListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			save();
		}
	};
	private OnClickListener cancelListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			if (isUpdated == false && isEdit == true)
			{
				isUpdated = checkForChanges();
			}
			
			if (isUpdated == true || isEdit == false)
			{
				showSaveWarning();
			} else 
			{
				getFragmentManager().popBackStack();
			}
		}
	};
	private OnClickListener notesEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			isUpdated = (isUpdated || checkForChanges() ? true : false);
			
			Bundle args = new Bundle();
			args.putString(Constants.EXTRA_FRAG_TAG, RigEditActivity.this.getTag());
			args.putString(Constants.EXTRA_NOTES, rig.getNotes());
			
			FragmentHelper.getInstance().openFragment(NotesEditActivity.newInstance(args), android.R.id.tabhost, 
					Constants.TAG_NOTES_EDIT, getFragmentManager());
		}
	};
	private OnClickListener componentEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			isUpdated = (isUpdated || checkForChanges() ? true : false);
			currentEditedComponent = (RigComponent)view.getTag();
			
			Bundle args = new Bundle();
			args.putString(Constants.EXTRA_FRAG_TAG, RigEditActivity.this.getTag());
			args.putBoolean(Constants.EXTRA_RIG_COMPONENT_IS_EDIT, true);
			args.putString(Constants.EXTRA_RIG_COMPONENT_NAME, currentEditedComponent.getName());
			args.putString(Constants.EXTRA_RIG_COMPONENT_SERIAL_NUMBER, currentEditedComponent.getSerialNumber());
			args.putString(Constants.EXTRA_RIG_COMPONENT_NOTES, currentEditedComponent.getNotes());

			FragmentHelper.getInstance().openFragment(RigComponentEditActivity.newInstance(args), android.R.id.tabhost, 
					Constants.TAG_RIG_COMPONENT_EDIT, getFragmentManager());
		}
	};
	private OnClickListener addComponentListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{	
			isUpdated = (isUpdated || checkForChanges() ? true : false);
			
			Bundle args = new Bundle();
			args.putString(Constants.EXTRA_FRAG_TAG, RigEditActivity.this.getTag());
			
			FragmentHelper.getInstance().openFragment(RigComponentEditActivity.newInstance(args), android.R.id.tabhost, 
					Constants.TAG_RIG_COMPONENT_EDIT, getFragmentManager());
		}
	};
	private OnClickListener reminderEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			isUpdated = (isUpdated || checkForChanges() ? true : false);
			currentEditedReminder = (RigReminder)view.getTag();
			
			Bundle args = new Bundle();
			args.putString(Constants.EXTRA_FRAG_TAG, RigEditActivity.this.getTag());
			args.putBoolean(Constants.EXTRA_RIG_REMINDER_IS_EDIT, true);
			args.putString(Constants.EXTRA_RIG_REMINDER_NAME, currentEditedReminder.getName());
			args.putInt(Constants.EXTRA_RIG_REMINDER_INTERVAL,	currentEditedReminder.getInterval());
			args.putSerializable(Constants.EXTRA_RIG_REMINDER_INTERVAL_UNIT, currentEditedReminder.getIntervalUnit());
			args.putSerializable(Constants.EXTRA_RIG_REMINDER_LAST_COMPLETED_DATE, currentEditedReminder.getLastCompletedDate());
			
			FragmentHelper.getInstance().openFragment(RigReminderEditActivity.newInstance(args), android.R.id.tabhost, 
					Constants.TAG_RIG_REMINDER_EDIT, getFragmentManager());
		}
	};
	private OnClickListener addReminderListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			isUpdated = (isUpdated || checkForChanges() ? true : false);
			
			Bundle args = new Bundle();
			args.putString(Constants.EXTRA_FRAG_TAG, RigEditActivity.this.getTag());
					
			FragmentHelper.getInstance().openFragment(RigReminderEditActivity.newInstance(args), android.R.id.tabhost, 
					Constants.TAG_RIG_REMINDER_EDIT, getFragmentManager());
		}
	};
	private OnClickListener deleteListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			showDeleteWarning();
		}
	};
	private DialogInterface.OnClickListener deleteConfirmListener = new DialogInterface.OnClickListener()
	{
		@Override
		public void onClick(DialogInterface arg0, int arg1)
		{
			delete();
		}
	};
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		// load data
		repository = new RigRepository(getActivity());
		loadData();
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
	    		Bundle savedInstanceState)
	{	
	    // Inflate the layout for this fragment
	    return inflater.inflate(R.layout.rig_edit_view, container, false);
	}

   @Override
    public void onResume()
    {
    	super.onResume();
    	
		// init ui
		initializeUI();
    }
	
	private void loadData()
	{
		// set isEdit flag
		isEdit = (getArguments().size() != 0 && getArguments().containsKey(Constants.EXTRA_RIG_ID));
		
		// determine add vs. edit
		if (isEdit)
		{
			// editing
			int id = getArguments().getInt(Constants.EXTRA_RIG_ID);
			rig = repository.getRig(id);
		}
		else
		{
			// adding
			rig = new Rig();
		}
	}
	
	private void initializeUI()
	{
		// set header text
		TextView headerTextView = (TextView) getActivity().findViewById(R.id.EditHeaderTextView);
		headerTextView.setText(isEdit ?
				R.string.rig_edit_label : R.string.rig_new_label);

		// set name
		EditText nField = (EditText) getActivity().findViewById(R.id.RigNameField);
		nField.setText(rig.getName());
		
		// set primary
		CheckBox pField = (CheckBox) getActivity().findViewById(R.id.RigPrimaryField);
		pField.setChecked(rig.isPrimary());
		
		if (!isEdit)
		{
			TableRow aRow = (TableRow) getActivity().findViewById(R.id.RigArchivedTablerow);
			aRow.setVisibility(View.GONE);
		}
		else
		{
			// set archived
			CheckBox aField = (CheckBox) getActivity().findViewById(R.id.RigArchivedField);
			aField.setChecked(rig.isArchived());
		}
		
		// set jump count
		TextView jcField = (TextView) getActivity().findViewById(R.id.RigJumpCountField);
		jcField.setText(rig.getJumpCount() == 0 ? "0" :
			FormatUtility.toNumericString(rig.getJumpCount()));
		
		// set notes
		TextView notesField = (TextView) getActivity().findViewById(R.id.RigNotesField);
		notesField.setText(rig.getNotes());
		notesField.setOnClickListener(notesEditListener);
		
		// init components UI
		initComponentsUI();
		
		// init reminders UI
		initRemindersUI();
		
		// add button listeners
		ImageButton saveButton = (ImageButton) getActivity().findViewById(R.id.RigEditSaveButton);
		saveButton.setOnClickListener(saveListener);
		
		ImageButton cancelButton = (ImageButton) getActivity().findViewById(R.id.RigEditCancelButton);
		cancelButton.setOnClickListener(cancelListener);
		
		ImageButton deleteButton = (ImageButton) getActivity().findViewById(R.id.RigEditDeleteButton);
		deleteButton.setOnClickListener(deleteListener);
		
		// show/hide delete button
		deleteButton.setVisibility(isEdit ? View.VISIBLE : View.GONE);
	}
	
	private void initComponentsUI()
	{
		TableLayout tableLayout = (TableLayout) getActivity().findViewById(R.id.RigComponentsTable);
		tableLayout.removeAllViews();
		for (int i = 0; i < rig.getComponents().size(); i++)
		{
			// get component
			RigComponent component = rig.getComponents().get(i);
			
			// create row, add to table
			TableRow row = createComponentTableRow(component, i == 0);
			tableLayout.addView(row);
		}
		
		// add 'add component' row
		TableRow addRow = createAddTableRow(
				rig.getComponents().size() <= 0,
				R.string.rig_add_component_label,
				addComponentListener);
		tableLayout.addView(addRow);
	}
	
	private void initRemindersUI()
	{
		TableLayout tableLayout = (TableLayout) getActivity().findViewById(R.id.RigRemindersTable);
		tableLayout.removeAllViews();
		for (int i = 0; i < rig.getReminders().size(); i++)
		{
			// get reminder
			RigReminder reminder = rig.getReminders().get(i);
			
			// create row, add to table
			TableRow row = createReminderTableRow(reminder, i == 0);
			tableLayout.addView(row);
		}
		
		// add 'add reminder' row
		TableRow addRow = createAddTableRow(
				rig.getReminders().size() <= 0,
				R.string.rig_add_reminder_label,
				addReminderListener);
		tableLayout.addView(addRow);
	}
	
	private TableRow createComponentTableRow(RigComponent component, boolean first)
	{
		// create table row
		TableRow row = new TableRow(getActivity());
		row.setTag(component);
		row.setOnClickListener(componentEditListener);
		// style
		TableStyler.styleTableRow(row, first ? TableRowLocation.First : TableRowLocation.Middle);
		
		// add component name
		TextView componentName = new TextView(getActivity());
		componentName.setText(component.getName());
		// style
		TableStyler.styleTableRowTextView(getActivity(), componentName, false, false, true, 1);
		// add to row
		row.addView(componentName);
		
		return row;
	}
	
	private TableRow createReminderTableRow(RigReminder reminder, boolean first)
	{
		// create table row
		TableRow row = new TableRow(getActivity());
		row.setTag(reminder);
		row.setOnClickListener(reminderEditListener);
		// style
		TableStyler.styleTableRow(row, first ? TableRowLocation.First : TableRowLocation.Middle);
		
		// add description
		TextView name = new TextView(getActivity());
		name.setText(reminder.getName());
		// style
		TableStyler.styleTableRowTextView(getActivity(), name, false, false, false, 1);
		// add to row
		row.addView(name);
		
		// update fields based on due status
		Drawable icon = null;
		int textStyleId = R.style.FormFieldValueStyle;
		if (reminder.getDueStatus() == DueStatus.DueSoon)
		{
			textStyleId = R.style.DueSoonTextStyle;
		}
		else if (reminder.getDueStatus() == DueStatus.PastDue)
		{
			textStyleId = R.style.PastDueTextStyle;
			icon = getResources().getDrawable(R.drawable.skull_small);
		}
		name.setTextAppearance(getActivity(), textStyleId);
		name.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
		
		return row;
	}
	
	private TableRow createAddTableRow(boolean solo, int textId, OnClickListener listener)
	{
		// add 'add component' row
		TableRow row = new TableRow(getActivity());
		row.setOnClickListener(listener);
		// style
		TableStyler.styleTableRow(row, solo ? TableRowLocation.Solo: TableRowLocation.Last);
		// add label
		TextView addLabel = new TextView(getActivity());
		addLabel.setText(textId);
		// style
		TableStyler.styleTableRowTextView(getActivity(), addLabel, false, true, true, 1);
		// add to row
		row.addView(addLabel);
		
		return row;
	}
	
	private void showDeleteWarning()
	{
		// create alert dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setMessage(R.string.rig_delete_warning);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle(R.string.delete_confirmation);
		builder.setPositiveButton(R.string.yes_button, deleteConfirmListener);
		builder.setNegativeButton(R.string.no_button, null);
		AlertDialog dialog = builder.create();
		// show dialog
		dialog.show();
	}
	
	public void updateNotes(String notes)
	{
		// update component
		rig.setNotes(notes);
	}
	
	public void updateComponent(String name, String serialNumber, String notes)
	{
		// update reminder and UI
		if (currentEditedComponent == null)
		{
			// add
			RigComponent component = new RigComponent();
			component.setName(name);
			component.setSerialNumber(serialNumber);
			component.setNotes(notes);
			rig.getComponents().add(component);
		}
		else
		{
			// update
			currentEditedComponent.setName(name);
			currentEditedComponent.setSerialNumber(serialNumber);
			currentEditedComponent.setNotes(notes);
		}
	}
	
	public void deleteComponent()
	{
		// delete
		rig.getComponents().remove(currentEditedComponent);
	}
	
	public void updateReminder(String name, int interval, TimeUnit intervalUnit, Date lastCompletedDate)
	{
		// update reminder and UI
		if (currentEditedReminder == null)
		{
			// add reminder
			RigReminder reminder = new RigReminder();
			reminder.setName(name);
			reminder.setInterval(interval);
			reminder.setIntervalUnit(intervalUnit);
			reminder.setLastCompletedDate(lastCompletedDate);
			rig.getReminders().add(reminder);
		}
		else
		{
			// update
			currentEditedReminder.setName(name);
			currentEditedReminder.setInterval(interval);
			currentEditedReminder.setIntervalUnit(intervalUnit);
			currentEditedReminder.setLastCompletedDate(lastCompletedDate);
		}
	}
	
	public void deleteReminder()
	{
		// delete
		rig.getReminders().remove(currentEditedReminder);
	}
	
	private void save()
	{
		checkForChanges();

		// save
		if (isEdit)
		{
			repository.updateRig(rig);
		}
		else
		{
			repository.addRig(rig);
		}
		
		if (getArguments().containsKey(Constants.EXTRA_FROM_GEAR_TAB))
		{
			MainActivity mainActivity = (MainActivity) getActivity();
			mainActivity.updateGearTab();
		}
		
		// update reminders
		RigReminderManager.getInstance().remindersChanged();
		
		// finish
		getFragmentManager().popBackStack();
	}
	
	private void delete()
	{
		// delete aircraft
		repository.deleteRig(rig);
		
		if (getArguments().containsKey(Constants.EXTRA_FROM_GEAR_TAB))
		{
			((MainActivity) getActivity()).updateGearTab();
		}
		
		// update reminders
		RigReminderManager.getInstance().remindersChanged();
		
		// finish
		getFragmentManager().popBackStack();
	}
	
	private Boolean checkForChanges()
	{
		Boolean returnValue = false;

		// check name
		EditText nField = (EditText) getActivity().findViewById(R.id.RigNameField);

		if (!rig.getName().equals(nField.getText().toString()))
		{
			returnValue = true;

			// set name
			rig.setName(nField.getText().toString());
		}
		
		// check primary
		CheckBox pField = (CheckBox) getActivity().findViewById(R.id.RigPrimaryField);
		
		if (rig.isPrimary() != pField.isChecked())
		{
			returnValue = true;

			// set primary
			rig.setPrimary(pField.isChecked());
		}
		
		// check archived
		CheckBox aField = (CheckBox) getActivity().findViewById(R.id.RigArchivedField);
		
		if (rig.isArchived() != aField.isChecked())
		{
			returnValue = true;

			// set archived
			rig.setArchived(aField.isChecked());
		}
		
		return returnValue;
	}
	
	private void showSaveWarning()
	{
		// create alert dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setMessage(R.string.gear_list_save_warning);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle(R.string.save_confirmation);
		builder.setPositiveButton(R.string.yes_button, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				save();
	           }       
		});
		builder.setNegativeButton(R.string.no_button, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				getFragmentManager().popBackStack();
	           }       
		});
			
		AlertDialog dialog = builder.create();
		// show dialog
		dialog.show();
	}
}
